
#
# llvm-lua source
#
set(NON_LLVM_SRC
	lua_core.c
	lua_vm_ops_static.c
	load_jit_proto.c
)
set(LLVM_COMMON_SRC
	LLVMCompiler.cpp
	llvm_compiler.cpp
	load_embedded_bc.cpp
	load_vm_ops.cpp
	lua_vm_ops_bc.h
	${NON_LLVM_SRC}
)
set(NO_JIT_SRC
	no_jit.c
	${NON_LLVM_SRC}
)
set(LLVM_LUA_SRC
	llvm-lua.cpp
	lua_interpreter.c
)
set(LLVM_LUAC_SRC
	llvm-luac.cpp
	lua_compiler.c
	LLVMDumper.cpp
	llvm_dumper.cpp
	load_liblua_main.cpp
	liblua_main_bc.h
)
set(LLVM_LUA_LIB_SRC
	lua_interpreter.c
	${LLVM_COMMON_SRC}
)
set(LLVM_LUA_BINS)
set(LUA_COMPILER)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}
				${PROJECT_SOURCE_DIR}/src
				${CMAKE_CURRENT_BINARY_DIR})

configure_file(
	"${CMAKE_CURRENT_SOURCE_DIR}/llvm_lua_config.h.in"
	"${CMAKE_CURRENT_BINARY_DIR}/llvm_lua_config.h"
	@ONLY
)

add_executable(bin2c bin2c.c)

# setup s-compiler flags.
# cflags for LLVM bitcode files.
if(CMAKE_BUILD_TYPE STREQUAL "Release")
	set(BC_CFLAGS "${COMMON_CFLAGS} ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_RELEASE}")
else()
	set(BC_CFLAGS "${COMMON_CFLAGS} ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_DEBUG}")
endif()
string(REGEX REPLACE "[ \t\n]+" ";" BC_CFLAGS ${BC_CFLAGS})
# ignore unused parameters in lua_vm_ops* files.
set(BC_CFLAGS ${BC_CFLAGS} -Wno-unused-parameter)
set(BC_CFLAGS ${BC_CFLAGS} -c -emit-llvm -I../src)

if(CROSS_COMPILE)
    set(BC_CFLAGS -arch ${CROSS_ARCH} ${BC_CFLAGS}) # -arch should be first param
    set(BC_CFLAGS ${BC_CFLAGS} -isysroot ${CROSS_SYSROOT})
    set(BC_CFLAGS ${BC_CFLAGS} ${CROSS_CFLAGS})
endif(CROSS_COMPILE)

#
# Embedded LLVM bitcode files
#
add_llvm_bc_library(lua_vm_ops lua_vm_ops.c)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lua_vm_ops_bc.h
	COMMAND bin2c -z -c ${CMAKE_CURRENT_BINARY_DIR}/lua_vm_ops.bc ${CMAKE_CURRENT_BINARY_DIR}/lua_vm_ops_bc.h
	WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
	DEPENDS bin2c ${CMAKE_CURRENT_BINARY_DIR}/lua_vm_ops.bc
)

if(CROSS_COMPILE)
    #add_llvm_bc_library(liblua_main lua_main.c ${NO_JIT_SRC})
    add_llvm_bc_library(liblua_main lua_llvm_lib.c ${NO_JIT_SRC})
else(CROSS_COMPILE)
    add_llvm_bc_library(liblua_main lua_llvm_lib.c ${NO_JIT_SRC})
    #add_llvm_bc_library(liblua_main lua_main.c ${NO_JIT_SRC})
endif(CROSS_COMPILE)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/liblua_main_bc.h
	COMMAND bin2c -z -c ${CMAKE_CURRENT_BINARY_DIR}/liblua_main.bc ${CMAKE_CURRENT_BINARY_DIR}/liblua_main_bc.h
	WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
	DEPENDS bin2c ${CMAKE_CURRENT_BINARY_DIR}/liblua_main.bc
)

#
# Lua library.
#
set(LLVM_LUA_LIBS)

if(WANT_STATIC_LIBRARY)
	# llvm-lua static library.
	add_library(llvm-lua_static STATIC ${LLVM_LUA_LIB_SRC})
	add_target_properties(llvm-lua_static COMPILE_FLAGS "${COMMON_CFLAGS} ${LLVM_CFLAGS}")
	add_target_properties(llvm-lua_static LINK_FLAGS "${LD_FLAGS} ${COMMON_LDFLAGS} ${LLVM_LFLAGS}")
	target_link_libraries(llvm-lua_static ${LIBS} ${LLVM_ALL_LIBS})

	# link lua interpreter with static library
	set(LLVM_LUA_MAIN_LIB llvm-lua_static)
	set(LLVM_LUA_LIBS ${LLVM_LUA_LIBS} llvm-lua_static)

	if (WANT_NOJIT_LIBRARIES)
		# lua static library without LLVM JIT support.
		add_library(llvm-lua_nojit_static STATIC ${NO_JIT_SRC})
		add_target_properties(llvm-lua_nojit_static COMPILE_FLAGS "${COMMON_CFLAGS}")
		add_target_properties(llvm-lua_nojit_static LINK_FLAGS "${LD_FLAGS} ${COMMON_LDFLAGS}")
		target_link_libraries(llvm-lua_nojit_static ${LIBS})

		set(LLVM_LUA_LIBS ${LLVM_LUA_LIBS} llvm-lua_nojit_static)
	endif (WANT_NOJIT_LIBRARIES)
endif(WANT_STATIC_LIBRARY)

#
# static library liblua_main.a
#
if(NOT CROSS_COMPILE)
	add_library(llvm-lua_main STATIC lua_main.c ${NO_JIT_SRC})
	add_target_properties(llvm-lua_main COMPILE_FLAGS "${COMMON_CFLAGS}")
	add_target_properties(llvm-lua_main LINK_FLAGS "${LD_FLAGS} ${COMMON_LDFLAGS}")

	set(LLVM_LUA_LIBS ${LLVM_LUA_LIBS} llvm-lua_main)
endif(NOT CROSS_COMPILE)

# set library version & soversion
if(LLVM_LUA_LIBS)
	set_target_properties(${LLVM_LUA_LIBS} PROPERTIES
		VERSION ${LLVM_LUA_VERSION}
		SOVERSION ${LLVM_LUA_SOVERSION}
		CLEAN_DIRECT_OUTPUT 1
	)
endif(LLVM_LUA_LIBS)

#
# Lua compiler
#
add_executable(llvm-luac ${LLVM_LUAC_SRC})
add_target_properties(llvm-luac COMPILE_FLAGS "${COMMON_CFLAGS} ${LLVM_CFLAGS}")
add_target_properties(llvm-luac LINK_FLAGS "${LD_FLAGS} ${COMMON_LDFLAGS} ${LLVM_LFLAGS}")
target_link_libraries(llvm-luac ${LLVM_LUA_MAIN_LIB} ${LLVM_ALL_LIBS})
set(LLVM_LUA_BINS llvm-luac)

#
# build as a cross-compiler
#
if(CROSS_COMPILE)
	set(LUA_COMPILER "${CMAKE_CURRENT_BINARY_DIR}/lua-cross-compiler")
    set_target_properties(llvm-luac PROPERTIES OUTPUT_NAME ${CROSS_ARCH}-llvm-luac)
	configure_file("${CMAKE_CURRENT_SOURCE_DIR}/lua-cross-compiler.in" "${LUA_COMPILER}" @ONLY)
else(CROSS_COMPILE)
	set(LUA_COMPILER "${CMAKE_CURRENT_BINARY_DIR}/lua-compiler")
	configure_file("${CMAKE_CURRENT_SOURCE_DIR}/lua-compiler.in" "${LUA_COMPILER}" @ONLY)
endif(CROSS_COMPILE)

#
# Lua stand-alone interpreter
#
if(NOT CROSS_COMPILE)
	add_executable(llvm-lua_binary ${LLVM_LUA_SRC})
	add_target_properties(llvm-lua_binary COMPILE_FLAGS "${COMMON_CFLAGS} ${LLVM_CFLAGS}")
	add_target_properties(llvm-lua_binary LINK_FLAGS
		"${LD_FLAGS} ${COMMON_LDFLAGS} ${LLVM_LFLAGS}")
	target_link_libraries(llvm-lua_binary ${LLVM_LUA_MAIN_LIB} ${LLVM_JIT_LIBS})
	# rename llvm-lua.bin to llvm-lua
	set_target_properties(llvm-lua_binary PROPERTIES OUTPUT_NAME llvm-lua)
	set(LLVM_LUA_BINS ${LLVM_LUA_BINS} llvm-lua_binary)
endif(NOT CROSS_COMPILE)

install(TARGETS ${LLVM_LUA_BINS}
    RUNTIME DESTINATION bin
)
install(FILES ${LUA_COMPILER}
    DESTINATION bin
    PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE
    WORLD_READ WORLD_EXECUTE
)

if(LLVM_LUA_LIBS)
    install(TARGETS ${LLVM_LUA_LIBS}
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib
    )
endif(LLVM_LUA_LIBS)


